/*
 * 轮播图插件，支持在手机上滑动
 * Author: rguanghui.stupid@gmail.com, rguanghui.sinaapp.com
 * Update: 2014.05.20
 * Verson: 1.0
 * @param {object} configs 需要的一些参数
 * configs.container 包裹层的id，默认为js-slide
 * configs.ul        譬如ul，这是为了可以兼容其他的html结构。
 * configs.li        譬如li，这是为了可以兼容其他的html结构。
 * configs.interval  自动播放的间隔，单位是秒
 * 其他说明：WP手机不含有touch事件，可用其独有的事件进行监听绑定，暂时不管。
 *         为了视觉效果，自动轮播时轮播图是循环播放的，但用手滑动时却是单向的。
 */

(function(window, undefined){
  
  var slide = function ( container, configs ) {
    configs || ( configs = {} );
    var defaults = {
      "container" : container || "js-slide",
      "ul"        : "ul",
      "li"        : "li",
      "interval"  : 4
    };
    for ( var i in defaults ) {
      configs[i] || ( configs[i] = defaults[i] );
    };
    this.init( configs );
  };
  
  slide.prototype = {
    init: function( configs ) {
      this.obj = ( typeof configs.container === "string" ) ? document.getElementById( configs.container ) : configs.container;
      this.ul = this.obj.querySelector( configs.ul );
      this.li = this.ul.querySelectorAll( configs.li );
      this.images = this.obj.querySelectorAll( "img" );
      this.numbers = document.createElement( "ul" );
      this.width = this.obj.offsetWidth;
      this.index = 0;
      this.startX = this.startY = 0;
      this.translateX = 0;
      this.moved = false;
      this.play = null;
      this.interval = configs.interval * 1000;
      this.setSize();
      this.autoPlay();
      this.bindTouch();
    },
    bindTouch: function() {
      // 绑定触摸事件
      this.obj.addEventListener("touchstart", (function( _this ) {
        return function() { 
          _this.touchStart.apply ( _this, arguments ); 
        };
      })(this), false);
      
      this.obj.addEventListener("touchmove", (function( _this ) {
        return function() {
          _this.touchMove.apply ( _this, arguments );
        }
      })(this), false);
      
      this.obj.addEventListener("touchend", (function( _this ) {
        return function() {
          _this.touchEnd.apply ( _this, arguments );
        }
      })(this), false);
      
      this.obj.addEventListener("touchcancel", (function( _this ) {
        return function() {
          _this.touchEnd.apply ( _this, arguments );
        }
      })(this), false);
    },
    setSize: function() {
      // 创建滑动方块
      var numHTML = "";
      this.numbers.setAttribute( "class", "slide-number" );
     
      this.ul.style.width = this.width * this.li.length + "px";
      for ( var i = 0; li = this.li[i]; i++ ) {
        li.style.width = this.width + "px";
        numHTML += "<li style='width:" + 100/this.li.length + "%' class=" + ( i == 0 ? 'current' : '' ) + "></li>";
      };
      this.numbers.innerHTML = numHTML;
      this.obj.appendChild( this.numbers );
      
      this.ul.style.webkitTransform = "translateX(0)";
          this.ul.style.msTransform = "translateX(0)";
            this.ul.style.transform = "translateX(0)";
      this.ul.style.webkitTransition = "-webkit-transform .8s ease-in-out";
          this.ul.style.msTransition = "-ms-transform .8s ease-in-out";
            this.ul.style.transition = "transform .8s ease-in-out";
      
    },
    autoPlay: function() {
      this.play = setInterval( (function( _this ) {
        return function() {
          _this.index++;
          // 自动滚动的时候循环滚动
          ( _this.index < 0 ) && ( _this.index = _this.li.length-1 );
          ( _this.index >= _this.li.length ) && ( _this.index = 0 );
          _this.move();
        }
      })(this), this.interval );
    },
    move: function( target ) {
      for ( var i = 0; item = this.numbers.children[i]; i++ ) {
      	item.classList.remove( "current" );
      };
      this.numbers.children[this.index].classList.add( "current" );
      this.ul.style.webkitTransform = "translateX(" + ( -this.index * this.width ) + "px)";
          this.ul.style.msTransform = "translateX(" + ( -this.index * this.width ) + "px)";
            this.ul.style.transform = "translateX(" + ( -this.index * this.width ) + "px)";
    },
    touchStart: function( e ) {
      clearInterval( this.play );
      e.preventDefault();
      // 记录初始位置
      var touch = e.touches[0];
      this.startX = touch.pageX;
      this.startY = touch.pageY;
    },
    touchMove: function( e ) {
      e.preventDefault();
      var touch = e.touches[0];
      // 记录移动的距离
      var x = touch.pageX - this.startX;
      var y = touch.pageY - this.startY;
      this.translateX = x;
      // 移动时不需要发生过渡动画
      this.ul.style.webkitTransitionDuration = "0ms";
      this.ul.style.webkitTransform = "translateX(" + ( -this.index * this.width + x / 1.2 ) + "px)";
          this.ul.style.msTransform = "translateX(" + ( -this.index * this.width + x / 1.2 ) + "px)";
            this.ul.style.transform = "translateX(" + ( -this.index * this.width + x / 1.2 ) + "px)";
    },
    touchEnd: function( e ) {
      e.preventDefault();
      // 判断手指滑动的距离，超出 1/3 时触发滚动
      var canMove = Math.abs( this.translateX ) > this.width / 3;
      if ( canMove ) {
        this.translateX > 0 ? this.index-- : this.index++;
      }
      // 设置inex，手指滑动时不循环滚动
      ( this.index < 0 ) && ( this.index =0 );
      ( this.index >= this.li.length - 1 ) && ( this.index = this.li.length - 1 );
      // 手机离开后重新记录移动距离
      this.translateX = 0;
      this.ul.style.webkitTransitionDuration = "300ms";
          this.ul.style.msTransitionDuration = "300ms";
            this.ul.style.transitionDuration = "300ms";
      // 滚动到需要的位置，并开启自动滚动
      this.move();
      this.autoPlay();
    }
  };
  
  //外部调用
  window.utuoSlide = function( container, configs ) {
    return function( container, configs ){
      window.addEventListener("load", function(){
        this.photoSlide = new slide ( container, configs );
      }, false);
      window.addEventListener("resize", function(){
        clearInterval( this.photoSlide.play );
        this.photoSlide = new slide ( container, configs );
      }, false);
    }( container, configs )
  };
})(window);
